/**
 * es8 对象属性描述
 * Object.getOwnPropertyDescriptors()
 * 方法的引入目的，主要是为了解决 Object.assign() 无法正确拷贝 get 属性和 set 属性的问题
 * 
 */


const people = {name:'oo',age:'xx'};
console.log(Object.getOwnPropertyDescriptor(people,'name'))
console.log(Object.getOwnPropertyDescriptors(people))

// 自己实现该方法
function getOwnPropertyDescriptors(obj) {
  const result = {};
  for (let key of Reflect.ownKeys(obj)) {
    result[key] = Object.getOwnPropertyDescriptor(obj, key);
  }
  return result;
}
console.log(getOwnPropertyDescriptors(people))

/*
source 对象的 foo 属性的值是一个赋值函数，
Object.assign 方法将这个属性拷贝给 target1 对象，
结果该属性的值变成了 undefined。
这是因为 Object.assign 方法总是拷贝一个属性的值，
而不会拷贝它背后的赋值方法或取值方法
*/
const source = {
  set foo(value) {
    console.log(value);
  }
};
 
const target1 = {};
Object.assign(target1, source);
console.log(Object.getOwnPropertyDescriptor(source, 'foo'))
console.log(Object.getOwnPropertyDescriptor(target1, 'foo'))


const source2 = {
  set foo(value) {
    console.log(value);
  }
};
 
const target2 = {};
Object.defineProperties(target2, Object.getOwnPropertyDescriptors(source2));
console.log(Object.getOwnPropertyDescriptor(target2, 'foo'))

/**
 * 浅拷贝一个对象
Object.assign() 方法只能拷贝源对象的可枚举的自身属性，同时拷贝时无法拷贝属性的特性们，
而且访问器属性会被转换成数据属性，也无法拷贝源对象的原型，该方法配合 Object.create() 方法可以实现上面说的这些。
 */
let obj = {name:'aqie'}
Object.create(
  Object.getPrototypeOf(obj), 
  Object.getOwnPropertyDescriptors(obj) 
);

/**
 * 创建子类
 */
function superclass() {}
superclass.prototype = {
  // 在这里定义方法和属性
};
function subclass() {}
subclass.prototype = Object.create(superclass.prototype, Object.getOwnPropertyDescriptors({
  // 在这里定义方法和属性
}));
